package org.fdy.common.framework.config;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.exception.StopMatchException;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.strategy.SaStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.fdy.common.framework.config.properties.SecurityProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.lang.reflect.Method;

/**
 * <p>说明：sa-token 配置 </P>
 *
 * @author: fangdayang
 * @create: 2023-10-20 00:20
 **/
@Slf4j
@Configuration
@RequiredArgsConstructor
public class SaTokenConfig implements WebMvcConfigurer {

    private final SecurityProperties securityProperties;
    /**
     * 注册sa-token的拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册 Sa-Token 的路由拦截器
        registry.addInterceptor(new SaInterceptor(handle -> {
                    try {
                        if (handle instanceof HandlerMethod) {
                            // 获取此请求对应的 Method 处理函数
                            Method method = ((HandlerMethod) handle).getMethod();

                            // 如果此 Method 或其所属 Class 标注了 @SaIgnore，则忽略掉鉴权
                            if (SaStrategy.me.isAnnotationPresent.apply(method, SaIgnore.class)) {
                                return;
                            }
                            // 注解校验
                            SaStrategy.me.checkMethodAnnotation.accept(method);
                        }
                    } catch (StopMatchException e) {
                        // 停止匹配，进入Controller
                    }
                }).isAnnotation(false))
                .addPathPatterns("/**")
                .excludePathPatterns(securityProperties.getExcludes());
    }
}
